// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 初始化数据库，前加cloud
const db = cloud.database()
// 限制读取的条数
const MAX_LIMIT = 100

// 云函数入口函数
// event是小程序端传递的参数,context是云函数运行状态
exports.main = async (event, context) => {
  // 将运动数据解密返回
  const weRunData = event.weRunData
  // 在export中调用此云函数，直接写函数名称调用(同步用户成长值)
  await GrowthValue(weRunData.data.stepInfoList)
  // 同步积分数据(将用户积分返回出去)
  return await Point(weRunData.data.stepInfoList)
}
// 同步微信运动数据使用 ,(同步成长值)
async function GrowthValue(weRunData) {
  // 获取用户信息
  const context = cloud.getWXContext()
  // 将30天的运动步数，遍历存入数据库
  weRunData.forEach(async item => {
    /**
     * 先根据timestamp（该用户每天运动的时间）查询历史的记录，
     * 如果数据库中不存在则添加记录，
     * 如果存在相同的数据,则比较之后更新
     */
    // 先查询历史运动记录
    let queryResult = await db.collection('user_growth_value').where({
      timestamp: item.timestamp,
      _openid: context.OPENID
    }).get()
    if (queryResult.data.length <= 0) {
      //  如果集合中不存在相同的运动数据则新增  添加运动记录
      await db.collection('user_growth_value').add({
        data: {
          _openid: context.OPENID, //用户id
          date: db.serverDate(), //存入数据库的时间，使用数据库的时间
          changeGrowthValue: item.step, //运动的步数
          opertion: '微信运动', //数据从哪里来的备注
          timestamp: item.timestamp, //运动步数的每天的时间
          orderId: '', //通过购物获得的步数备注
          noteId: '' //通过发布笔记获得的步数备注
        }
      })
    } else {
      // 如果在此日期的步数大于数据库中的步数
      if (item.step > queryResult.data[0].changeGrowthValue) {
        // 则根据数据id把当前步数更新成最新的数据
        await db.collection('user_growth_value').doc(queryResult.data[0]._id).update({
          data: {
            changeGrowthValue: item.step,
            data: db.serverDate()
          }
        })
      }
    }
  })
  /**
   * 更新用户总成长值
   * 数据库读取每次最多读取100条,如果读取数据过多,分次读取
   * 首先获取总天数的记录数
   * 设置每次读取的记录数量
   * 最后计算出要分几次读取
   */

  //  获取总的记录数
  const countResult = await db.collection('user_growth_value').count()
  const total = countResult.total
  // 总共要读取的次数
  const pageCount = Math.ceil(total / MAX_LIMIT)
  // 创建变量存储读取操作的promise
  const tasks = []
  for (let i = 0; i < pageCount; i++) {
    let promise = db.collection('user_growth_value').where({
      _openid: context.OPENID
    }).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
    tasks.push(promise)
  }
  var allGrowthValueRecords = (await Promise.all(tasks)).reduce((acc, cur) => ({
    data: acc.data.concat(cur.data),
    errMsg: acc.errMsg
  }))
  // 记录用户总的成长值
  var totalGrowthValue = 0
  allGrowthValueRecords.data.forEach(item => {
    totalGrowthValue += item.changeGrowthValue
  })

  // 将总的成长值更新到user集合中
  db.collection('user').where({
    _openid: context.OPENID
  }).update({
    data: {
      growthValue: totalGrowthValue
    }
  })
}
// 同步微信运动数据使用 ,(同步积分)
async function Point(weRunData) {
  const context = cloud.getWXContext()
  // 创建数组，存储本次获取积分的详细信息，给小程序端显示
  const weRunPoint = []
  // 存储用户本次的运动数据
  for (let i in weRunData) {
    weRunPoint.push({
      time: weRunData[i].timestamp, //每天的日期
      step: weRunData[i].step, //运动的步数
      changePoint: 0 // 存储的时本次同步的积分数
    })
  }
  for (let i in weRunData) {
    let data = weRunData[i] //声明变量存储本次循环的微信运动数据
    // let result = weRunPoint[i] //声明变量存储本次循环的积分数据
    const queryResult = await db.collection('user_point').where({
      _openid: context.OPENID,
      timestamp: data.timestamp
    }).get()
    if (queryResult.data.length <= 0) {
      // 新增积分获取记录
      await db.collection('user_point').add({
        data: {
          _openid: context.OPENID,
          date: db.serverDate(),
          changePoints: data.step, //积分变动值，消耗积分为负值
          operation: '微信运动', //获取积分来源描述
          timestamp: data.timestamp, //运动数据ID
          orderId: '' //商城订单ID
        }
      })
      // 如果是今天首次同步数据，则本次同步数据=本次同步的步数
      weRunPoint[i].changePoint = data.step
    } else {
      // 更新用户此次的积分获取记录
      if (queryResult.data[0].changePoints < data.step) {
        await db.collection('user_point').doc(queryResult.data[0]._id).update({
          data: {
            changePoints: data.step,
            date: db.serverDate()
          }
        })
        // 如果本日期不是首次同步，则本次同步积分=本次步数-上次同步的步数
        weRunPoint[i].changePoint = data.step - queryResult.data[0].changePoints
      }
    }
  }
  /**
   * 更新用户的总的积分
   * 1）因为云数据库读取的限制，如果记录数量过多，无法一次全部读取，所以需要分批次读取
   * 2）首先获取总的记录数，然后设定每次要读取的记录数量，最后计算出分几次读取(Math.ceil(count/limit))
   */
  // 获取总的记录数
  const countResult = await db.collection('user_point').count()
  const total = countResult.total

  // 计算读取次数
  const pageCount = Math.ceil(total / MAX_LIMIT)
  // 创建变量，用户存储读取操作的promise
  const tasks = []
  for (let i = 0; i < pageCount; i++) {
    let promise = db.collection('user_point').where({
      _openid: context.OPENID
    }).skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
    tasks.push(promise)
  }
  var allPointValueRecords = (await Promise.all(tasks)).reduce((acc, cur) => ({
    data: acc.data.concat(cur.data),
    errMsg: acc.errMsg
  }))
  // 声明变量，存储用户总的积分
  var totalPointValue = 0
  allPointValueRecords.data.forEach(item => {
    totalPointValue += item.changePoints
  })
  console.log(totalPointValue)
  // 将总的成长值更新到user集合中
  db.collection('user').where({
    _openid: context.OPENID
  }).update({
    data: {
      point: totalPointValue
    }
  })
  return weRunPoint
}